/*
 * Copyright 2003-2007 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

package com.colony.zone;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import com.argot.TypeException;
import com.argot.TypeOutputStream;
import com.argot.TypeWriter;
import com.argot.remote.MetaLocation;

/**
 *  This object represents a Colony URL.  It has the form crl://host[:port]/location  
 */

public class CRL
implements MetaLocation
{
	public static final String TYPENAME = "crl";
	
    private URI _uri;
    
    public CRL(String host, String location, String name) 
    throws URISyntaxException
    {
        String path;

        if (location.endsWith("/"))
            path = location + name;
        else
            path = location + "/" + name;

        _uri = new URI("crl", host, path, null);
        check();
    }
    
    public CRL(String host, String path) 
    throws URISyntaxException
    {
        _uri = new URI("crl", host, path, null);
        check();
    }

    public CRL(String crl) 
    throws URISyntaxException
    {
        _uri = new URI(crl);
        check();
    }

	public CRL(CRL crl)
	throws URISyntaxException
	{
		this(crl.toString());
	}
    
    public CRL(CRL location, String path) 
    throws URISyntaxException 
    {
		this( location.getHost(), location.getPath(), path );
	}
    
    private void check() 
    throws URISyntaxException
    {
        // CRL no good without a host.
        String host = _uri.getHost();
        if (host == null)
            throw new URISyntaxException("not complete: no host", _uri.toString());

        // we only accept a live scheme.
        String scheme = _uri.getScheme();
        if (scheme == null)
            throw new URISyntaxException("not complete: no scheme",_uri.toString());
        if (!scheme.toLowerCase().equals("crl"))
            throw new URISyntaxException("wrong scheme '", scheme + "'");
        String path = _uri.getPath();

        // Don't like empty paths.  They'll confuse us later.
        if (path.equals(""))
            _uri = new URI(_uri.toString() + "/");

        // Clean up the path and make a new URI.
        String[] parts = path.split("/");
        for (int x=0; x<parts.length;x++)
        {
        	String part = parts[x];
        	if (part!=null)
        	{
        		if ("".equals(part))
        		{
        			parts[x] = null;
        		}
        		else if (".".equals(part))
        		{
        			parts[x] = null;
        		} 
        		else if ("..".equals(part))
        		{
        			parts[x] = null;
        			if (x==0)
        				throw new URISyntaxException("Invalid path supplied", _uri.toString() );

        			// look backward in path for first non empty part.
        			boolean found = false;
        			for (int y=x-1;y>0;y--)
        			{
        				if (parts[y]!=null)
        				{
        					
        					parts[y] = null;
        					found = true;
        					break;
        				}
        			}
        			if ( !found )
        				throw new URISyntaxException("Invalid path supplied", _uri.toString());
        		}	
        	}
        }
        
        StringBuffer buffer = new StringBuffer();
        for (int x=0;x<parts.length;x++)
        {
        	if (parts[x]!=null)
        	{
       			buffer.append("/");
        		buffer.append(parts[x]);
        	}
        }
        _uri = new URI(_uri.getScheme(),_uri.getHost(),buffer.toString(),null);
    }



	public void setHost( String host )
    {
    	
    }
    
	public String toString()
	{
		return _uri.toString();
	}
	
    public String getFullLocation()
    {
        return _uri.toString();
    }

    public String getHost()
    {
        return _uri.getHost();
    }

    public String getPath()
    {
        return _uri.getPath();
    }

    // Returns the path of the CRL without the last name.
    // ie it returns the directory the object is in.

    public String getLocation()
    {
        String path = _uri.getPath();
        int lastSlash = 0;
        int nextSlash = 0;

        nextSlash = path.indexOf('/');
        while (nextSlash >= 0)
        {
            lastSlash = nextSlash;
            nextSlash = path.indexOf('/', lastSlash + 1);
        }
        if (lastSlash==0)
        {
        	return "";
        }
        return path.substring(0, lastSlash + 1);
    }

    // Get the name of the object without the path.
    // getLocation() + "/" + getName() == getPath()

    public String getName()
    {
        String path = _uri.getPath();
        int lastSlash = 0;
        int nextSlash = 0;

        nextSlash = path.indexOf('/');
        while (nextSlash >= 0)
        {
            lastSlash = nextSlash;
            nextSlash = path.indexOf('/', lastSlash + 1);
        }
        return path.substring(lastSlash + 1);
    }

    // Returns the number of bits in the path.

    public int getPathSize()
    {
        String path = _uri.getPath();
        int size = 0;
        int nextSlash = 0;

        nextSlash = path.indexOf('/');
        while (nextSlash >= 0)
        {
            nextSlash = path.indexOf('/', nextSlash + 1);
            size++;
        }
        return size;
    }

    // get a specific name in the path.

    public String getPathPart(int i)
    {
        String path = _uri.getPath();
        int nextSlash = 0;
        int endSlash = 0;
        int c = i;

        // find the start of the slash.  
        nextSlash = path.indexOf('/');
        while (c > 0)
        {
            nextSlash = path.indexOf('/', nextSlash + 1);
            c--;
        }

        // gone past the end?
        if (nextSlash < 0)
        {
            return null;
        }

        // find the end Slash.
        endSlash = path.indexOf('/', nextSlash + 1);

        if (endSlash >= 0)
        {
            return path.substring(nextSlash + 1, endSlash);
        }

        return path.substring(nextSlash + 1);
    }
    
    
	public boolean isSameBase(CRL crl) {
		String thisCrl = this.toString();
		String otherCrl = crl.toString();
		if (thisCrl.length()>otherCrl.length())
			return thisCrl.startsWith(otherCrl);
		else
			return otherCrl.startsWith(thisCrl);
	}
	
    public static class CRLTypeWriter
    implements TypeWriter
    {
		public void write( TypeOutputStream out, Object o) 
		throws TypeException, IOException
		{
			CRL crl = (CRL) o;
			
			out.writeObject( "u8ascii", crl.getFullLocation() );
		}
    	
    }



}
